import React, { Component } from 'react';
import { View, Text, ScrollView, Platform } from 'react-native';
import _ from 'lodash';
import { observer } from 'mobx-react';
import * as Items from './items';
import store from './store';
import styles from './styles';
import OptionsIOS from './items/Selecter/optionsIOS';
import DateIOS from './items/Date/dateIOS';

class Form extends Component {
  state = {
    values: this.props.values || {},
    errors: this.props.errors || {},
    reload: undefined
  };
  componentWillMount() {
    this.props.store.init(this.props.fields);
  }
  onChange = (key, value) => {
    store.setValue(key, value);
  };
  /* 这个生命周期异步的，出发后并不直接执行内部函数，而是将其推入延迟执行栈里
  转而执行其他同步逻辑，
  两个表单跳转时出现问题，第一个表单销毁时，第二个表单初始化，初始化完成后，第一个表单触发的clear被执行，导致第二个表单的初始化白干了
  多个表单共用同一个store就是这结果，目前业务来看没必要保存每个表单的数据，没有同时出现多表单域的情况
  现在清理逻辑放在初始化之前在store里
  componentWillUnmount() {
    store.clear();
  }
  */
  renderFields = fields => {
    return _.map(fields, (field, i) => {
      const { type, initialValue, key, title, extra, ...itemProps } = field;
      if (type === 'Title') {
        const Item = Items[type];
        return (
          <View style={styles.itemWrap} key={`title_${i}`}>
            <Item title={title} />
          </View>
        );
      }
      const _props = {
        onChange: this.onChange.bind(null, key),
        initialValue,
        value: this.props.values[key],
        error: this.props.errors[key],
        fieldKey: key,
        ...itemProps
      };
      if (Items.hasOwnProperty(type)) {
        const Item = Items[type];
        return (
          <View style={styles.itemWrap} key={`form_${key}`}>
            <Item {..._props} />
            {this.renderExtra(extra, this.props.values[key])}
          </View>
        );
      } else {
        return null;
      }
    });
  };
  renderExtra = (eta, value) => {
    if (eta && _.isFunction(eta)) {
      const Extra = eta;
      return <Extra value={value} />;
    } else {
      return null;
    }
  };
  onSubmit = () => {
    store.validate((err, val) => {
      if (_.isFunction(this.props.onSubmit)) {
        this.props.onSubmit(val)
      }
    })
  }
  render() {
    return (
      <View style={styles.formWrap}>
        <View>{this.props.top || null}</View>
        <ScrollView style={styles.fieldsWrap}>
          {this.renderFields(this.props.fields)}
          {/* {<Text>{JSON.stringify(this.props.values, null, 2)}</Text>} */}
        </ScrollView>
        <View
          style={{
            padding: 5,
          }}
        >
          {this.props.bottom || null}
        </View>
        {
          Platform.OS === 'ios' && this.props.activePicker.key ? <OptionsIOS
            fieldKey={this.props.activePicker.key}
            value={this.props.activePicker.value}
            options={this.props.activePicker.options || []}
          /> : null
        }
        {
          Platform.OS === 'ios' && this.props.activeDate.key ? <DateIOS
            fieldKey={this.props.activeDate.key}
            value={this.props.activeDate.value}
            minDate={this.props.activeDate.minDate}
            maxDate={this.props.activeDate.maxDate}
            mode={this.props.activeDate.mode}
          /> : null
        }
      </View>
    );
  }
}

let Res;
try {
  Res = observer(props => (
    <Form
      {...props}
      store={store}
      values={store.values}
      errors={store.errors}
      activePicker={store.activePicker}
      activeDate={store.activeDate}
      hasError={store.hasError}
    />
  ));
} catch (error) {
  global.bugsnag.notify(error, (report) => {
    report.metadata = {
      "module": {
        "name": "Former",
      }
    }
  })
}
export default Res
export const validate = store.validate;
export const getFieldsValue = store.getValues;
export const getFieldValue = store.getValue;
export const setFieldsValue = store.setValues;
export const setFieldValue = store.setValue;
export const formStore = store;
export const parseErrors = error => {
  const _error = error.slice();
  if (_.isArray(_error) && _error.length > 0) {
    return _
      .map(_error, ({ name, message }) => `${name}-${message}`)
      .join('\n');
  }
};
